﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Model01.Logic;

namespace ForTraficProject
{    
    public class Convertor
    {
        private static byte[,] mapPassability;

        /// <summary>
        /// Set point on the map. If current color equals pattern color then this point will be 0 (free) else 1 (busy).
        /// </summary>
        /// <param name="current"></param>
        /// <param name="pattern"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private static void SetMapPoint(Color current, Color pattern, int x, int y)
        {
            if (current.R == pattern.R && current.G == pattern.G && current.B == pattern.B)
                mapPassability[y, x] = 0;
            else
                mapPassability[y, x] = 1;
        }

        /// <summary>
        /// Convert bitmap to passability matrix for Map. Color - color of free place.
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="color"></param>
        private static void ConvertBitmap(Bitmap bitmap, Color color)
        {
            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
            try
            {
                unsafe
                {
                    byte* pixels = (byte*)bitmapData.Scan0.ToPointer();
                    for (int y = 0; y < bitmapData.Height; y++)
                    {
                        for (int x = 0; x < bitmapData.Width * 3; x += 3)
                            SetMapPoint(Color.FromArgb(pixels[x], pixels[x + 1], pixels[x + 2]), color, x / 3, y);
                        pixels += bitmapData.Stride;
                    }
                }
            }
            finally
            {
                bitmap.UnlockBits(bitmapData);
            }
        }

        /// <summary>
        /// Serialize instance of Map with mapPassability matrix to file fileName.
        /// </summary>
        /// <param name="fileName"></param>
        public static void Save(string fileName)
        {
            Map map = new Map(mapPassability);
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();
            try
            {
                formatter.Serialize(fs, map);
            }
            catch (SerializationException e)
            {
                MessageBox.Show("Ошибка сериализации: " + e.Message);
            }
            finally
            {
                fs.Close();
            }
        }

        /// <summary>
        /// Convert bitmap fileName to Map.
        /// </summary>
        /// <param name="fileName"></param>
        public static void Convert(string fileName)
        {
            Bitmap bitmap = new Bitmap(Bitmap.FromFile(fileName));
            mapPassability = new byte[bitmap.Height, bitmap.Width];
            ConvertBitmap(bitmap, Color.White);
        }
    }
}
